package com.pan.common.interview.thread;

/**
 * 中断线程执行
 * stop方法、suspend、resume方法过于暴利，直接中断其他线程，容易产生问题，都被抛弃了
 * 调用interrupt方法，通知线程应该中断了
 *   1、如果线程处于被阻塞状态（sleep，wait，join状态），那么线程将立即退出被阻塞状态，并抛出一个InterruptionException异常
 *   2、如果线程处于正常活动状态，那么会将该线程的中断标志改为true，被设置的中断标志线程将继续正常进行，不受影响。
 *
 * interrupt方法需要被调用的线程配合中断
 *  如果线程又被临时中断的需求，则需要：
 *  1、在正常任务时，经常检查本线程的中断标志位，如果被设置了中断标志，则自行终止线程
 *  2、如果线程处于正常活动状态，那么会将该线程的中断标志改为true，被设置的中断标志线程将继续正常进行，不受影响。
 */
public class InterruptDemo {


    public static void main(String[] args) throws InterruptedException {
        Runnable interruptTask = new Runnable() {
            @Override
            public void run() {
                int i = 0;
                try {
                    //在正常运行任务时，经常检查本线程的中断标志位，如果被设置了中断标志就自行停止线程
                    while (!Thread.currentThread().isInterrupted()) {
                        Thread.sleep(100); // 休眠100ms
                        i++;
                        System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") loop " + i);
                    }
                } catch (InterruptedException e) {
                    //在调用阻塞方法时正确处理InterruptedException异常。（例如，catch异常后就结束线程。）
                    System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") catch InterruptedException.");
                }
            }
        };
        Thread t1 = new Thread(interruptTask, "t1");
        System.out.println(t1.getName() +" ("+t1.getState()+") is new.");

        t1.start();                      // 启动“线程t1”
        System.out.println(t1.getName() +" ("+t1.getState()+") is started.");

        // 主线程休眠300ms，然后主线程给t1发“中断”指令。
        Thread.sleep(300);
        t1.interrupt();
        System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");

        // 主线程休眠300ms，然后查看t1的状态。
        Thread.sleep(300);
        System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");
    }
}
